package com.hqq.helper;

import com.hqq.annotation.Aspect;
import com.hqq.annotation.Controller;
import com.hqq.annotation.Service;
import com.hqq.util.ClassUtil;
import com.hqq.util.ConfigUtil;

import java.util.HashSet;
import java.util.Set;

/**
 * ClassHelper
 * 类帮助类
 * 用于获取一个包下的所有类,所有Controller类,所有Service类
 * <p>
 * Created by heqianqian on 2017/7/19.
 */
public class ClassHelper {

    private static final Set<Class<?>> CLASS_SET;

    static {
        CLASS_SET = ClassUtil.getClassSet(ConfigUtil.getProjectBasePackage());
    }

    /**
     * 获取包下的所有类
     */
    public static Set<Class<?>> getClasses() {
        return CLASS_SET;
    }

    /**
     * 获取所有Controller注解的类
     *
     * @return Set<Class>
     */
    public static Set<Class<?>> getControllerClasses() {
        return getAnnotationClass(Controller.class);
    }

    /**
     * 获取所有Service注解的类
     *
     * @return Set<Class>
     */
    public static Set<Class<?>> getServiceClasses() {
        return getAnnotationClass(Service.class);
    }

    /**
     * 获取所有Aspect注解的类
     *
     * @return Set<Class>
     */
    public static Set<Class<?>> getAspectClasses(){
        return getAnnotationClass(Aspect.class);
    }

    /**
     * 获得包下所有的bean类
     *
     * @return Set<Class>
     */
    public static Set<Class<?>> getBeans() {
        Set<Class<?>> beanClasses = new HashSet<>();
        beanClasses.addAll(getControllerClasses());
        beanClasses.addAll(getServiceClasses());
        return beanClasses;
    }

    /**
     * 获取一个父类[接口]的所有子类
     *
     * @param superClass 父类
     * @return 所有子类
     */
    public static Set<Class<?>> getClassSetBySuper(Class<?> superClass) {
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz : CLASS_SET) {
            if (superClass.isAssignableFrom(clazz) && !superClass.equals(clazz)) {
                classSet.add(clazz);
            }
        }
        return classSet;
    }


    /**
     * 获取指定注解的类
     *
     * @param annotationClass 注解类型
     * @return Set<Class>
     */
    public static Set<Class<?>> getAnnotationClass(Class<?> annotationClass) {
        Set<Class<?>> classSet = new HashSet<>();
        for (Class clazz : CLASS_SET) {
            if (clazz.isAnnotationPresent(annotationClass)) {
                classSet.add(clazz);
            }
        }
        return classSet;
    }

}
